package com.north.light.libmediatemplate.widget.touch

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import com.north.light.libmediatemplate.utils.KtLogUtil

/**
 * FileName: TemplateTouchImageView
 * Author: lzt
 * Date: 2023/7/10 15:48
 * Description:自定义拖拽imageview
 */
class TemplateTouchImageView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : androidx.appcompat.widget.AppCompatImageView(context, attrs) {


    //能否能进行拖拽
    private var canMoveView = true

    private var lastX = 0f
    private var lastY = 0f


    private var downTouchX = 0f
    private var downTouchY = 0f
    private var clickEventInterval = 10


    private var mViewClickListener: ViewClickListener? = null


    override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
        KtLogUtil.d("TemplateTouchImageView dispatchTouchEvent")
        parent?.requestDisallowInterceptTouchEvent(true)
        return super.dispatchTouchEvent(event)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        dealWithTouchWhenNormalDispatch(event)
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                parent?.requestDisallowInterceptTouchEvent(true)
                KtLogUtil.d("TemplateTouchImageView ACTION_DOWN")
                dealWithTouchPosWhenCanMove(event)
                return true
            }
            MotionEvent.ACTION_MOVE -> {
                parent?.requestDisallowInterceptTouchEvent(true)
                dealWithTouchPosWhenCanMove(event)
                KtLogUtil.d("TemplateTouchImageView ACTION_MOVE")
                return true
            }
            MotionEvent.ACTION_CANCEL -> {
                parent?.requestDisallowInterceptTouchEvent(false)
                KtLogUtil.d("TemplateTouchImageView ACTION_CANCEL")
                dealWithTouchPosWhenCanMove(event)
                return false
            }
            MotionEvent.ACTION_UP -> {
                parent?.requestDisallowInterceptTouchEvent(false)
                KtLogUtil.d("TemplateTouchImageView ACTION_UP")
                dealWithTouchPosWhenCanMove(event)
                return false
            }
        }
        return super.onTouchEvent(event)
    }


    //判断移动距离是否大于某个距离，否则认为是点击事件
    private fun dealWithTouchWhenNormalDispatch(event: MotionEvent?) {
        val trainEvent = event ?: return
        when (trainEvent.action) {
            MotionEvent.ACTION_DOWN -> {
                downTouchX = trainEvent.x
                downTouchY = trainEvent.y
            }
            MotionEvent.ACTION_MOVE -> {

            }
            MotionEvent.ACTION_CANCEL -> {

            }
            MotionEvent.ACTION_UP -> {
                val currentX = trainEvent.x
                val currentY = trainEvent.y
                if (Math.abs(currentX - downTouchX) < clickEventInterval ||
                    Math.abs(currentY - downTouchY) < clickEventInterval
                ) {
                    mViewClickListener?.click(this)
                }
            }
        }
    }


    /**
     * 能分发情况下，事件处理逻辑
     * */
    private fun dealWithTouchPosWhenCanMove(event: MotionEvent?) {
        if (!canMoveView()) {
            return
        }
        val trainEvent = event ?: return
        val touchX = event.x
        val touchY = event.y
        when (trainEvent.action) {
            MotionEvent.ACTION_DOWN -> {
                lastX = touchX
                lastY = touchY
            }
            MotionEvent.ACTION_MOVE -> {
                val offsetX = touchX - lastX
                val offsetY = touchY - lastY

                //移动到边界的判断
                var start = (left + offsetX).toInt()
                var end = (right + offsetX).toInt()
                var top = (top + offsetY).toInt()
                var bottom = (bottom + offsetY).toInt()


                if (start <= 0) {
                    //水平越界
                    start = 0
                    end = measuredWidth
                }

                if (top <= 0) {
                    top = 0
                    bottom = measuredHeight
                }

                val parentView = parent
                if (parentView is View) {
                    val parentWidth = parentView.measuredWidth
                    if (end > parentWidth) {
                        start = parentWidth - measuredWidth
                        end = parentWidth
                    }
                    if (bottom > parentView.measuredHeight) {
                        bottom = parentView.measuredHeight
                        top = bottom - measuredHeight
                    }
                }

                layout(start, top, end, bottom)
            }
            MotionEvent.ACTION_CANCEL -> {

            }
            MotionEvent.ACTION_UP -> {
                updateParentPos()
            }
        }

    }

    /**
     * 更新当前view在父布局中的位置
     * */
    private fun updateParentPos() {
        val parentView = parent
        if (parentView is ConstraintLayout) {
            if (id == View.NO_ID || parentView.id == View.NO_ID) {
                return
            }
            val id = id
            val parentId = parentView.id
            val set = ConstraintSet()
            set.clone(parentView)
            set.connect(id, ConstraintSet.START, parentId, ConstraintSet.START)
            set.connect(id, ConstraintSet.TOP, parentId, ConstraintSet.TOP)
            val startPos = x.toInt()
            val topPos = y.toInt()
            KtLogUtil.d("updateParentPos startPos: $startPos top: $topPos")
            set.setMargin(id, ConstraintSet.START, startPos)
            set.setMargin(id, ConstraintSet.TOP, topPos)
            set.applyTo(parentView)
        }
    }


    /**
     * 更新能否进行事件分发的标识
     * */
    fun canMoveView(canMoveView: Boolean) {
        this.canMoveView = canMoveView
    }

    /**
     * 能否移动view
     * */
    fun canMoveView(): Boolean {
        return this.canMoveView
    }

    fun setViewClickListener(listener: ViewClickListener) {
        this.mViewClickListener = listener
    }

    interface ViewClickListener {
        fun click(v: View)
    }
}